<template>
  <div class="media-chat">
    <!-- 视频容器：本地 + 动态远程用户 -->
    <div class="video-container">
      <!-- 本地视频（固定） -->
      <div class="local-video-wrapper">
        <MultiMediaStream
          ref="localMedia"
          is-local
          autoStart
          @stream-data="handleLocalStream"
          @error="handleMediaError"
          @status-change="handleLocalStatusChange"
        />
        <div class="video-label">我</div>
        <div v-if="!inRoom" class="overlay-message">请先进入房间</div>
      </div>

      <!-- 动态生成远程用户视频 -->
      <div v-for="user in filteredRemoteUsers" :key="user.id" class="remote-video-wrapper">
        <MultiMediaStream :ref="el => (remoteMedias[user.id] = el)" :is-local="false" @error="handleMediaError" />
        <div class="video-label">
          {{ user.name }}
          <span v-if="!remoteStatus[user.id]?.isAudioActive">🔇</span>
          <span v-if="!remoteStatus[user.id]?.isVideoActive">📹</span>
        </div>
      </div>
    </div>

    <!-- 控制按钮区域（保持不变） -->
    <div class="controls">
      <button class="voice-button" @click="toggleCameraSource">
        <span>翻转摄像头</span>
      </button>
      <!-- <button class="voice-button" @click="toggleMicrophone" :disabled="!inRoom || !isConnected">
        <span v-if="localStatus.isMicrophoneOn">关闭麦克风</span>
        <span v-else>开启麦克风</span>
      </button>-->

      <button class="video-button" @click="toggleCamera" :disabled="!inRoom || !isConnected || !isVideoSupported">
        <span v-if="localStatus.isCameraOn">关闭摄像头</span>
        <span v-else>开启摄像头</span>
        <span v-if="!isVideoSupported" class="unsupported-indicator">不支持</span>
      </button>

      <!-- <button class="hangup-button" @click="endMediaCall" :disabled="!inRoom || !isConnected">结束通话</button> -->
    </div>

    <!-- 状态指示（保持不变） -->
    <div class="status-bar">
      <div class="status-indicator voice" :class="{ active: localStatus.isMicrophoneOn }"></div>
      <div class="status-indicator video" :class="{ active: localStatus.isCameraOn }"></div>
      <div class="connection-status" :class="{ connected: isConnected, error: hasError, disabled: !inRoom }">
        <template v-if="!inRoom">未进入房间</template>
        <template v-else>{{ connectionStatus }}</template>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, watch, defineEmits, defineExpose, toRefs, nextTick } from 'vue'
import MultiMediaStream from './MultiMediaStream.vue'

// 媒体类型常量
const MEDIA_TYPES = {
  AUDIO: 'audio',
  VIDEO: 'video',
  VIDEOFIRST: 'videoFirst'
}

// 接收父组件传入的参数
const props = defineProps({
  inRoom: { type: Boolean, required: true, default: false },
  roomId: { type: String, required: true, default: '' },
  currentUserId: { type: String, required: true, default: '' },
  onlineUsers: { type: Array, required: true, default: () => [] } // 房间用户列表
})

// 解构props
const { inRoom, roomId, currentUserId, onlineUsers } = toRefs(props)

// 状态管理
const localMedia = ref(null)
const remoteMedias = ref({}) // 远程用户媒体组件映射 { userId: 组件实例 }
const localStatus = ref({
  isMicrophoneOn: false,
  isCameraOn: false
})
const remoteStatus = ref({}) // 远程用户状态 { userId: { isAudioActive, isVideoActive } }
const streamTimers = ref({}) // 数据流计时器 { userId: { audio: timerId, video: timerId } }
const isConnected = ref(false)
const connectionStatus = ref('未连接')
const hasError = ref(false)
const isVideoSupported = ref(true)

// 过滤出除自己之外的在线用户
const filteredRemoteUsers = ref([])
watch(
  onlineUsers,
  async newUsers => {
    if (localMedia.value) {
      if (filteredRemoteUsers.value.length < newUsers.length) {
        console.log('addUserRestart')
        localMedia.value.restart()
      }
    }

    filteredRemoteUsers.value = newUsers.filter(item => item.id !== currentUserId.value)
    // 初始化新用户状态
    filteredRemoteUsers.value.forEach(userId => {
      if (!remoteStatus.value[userId]) {
        remoteStatus.value[userId] = {
          isMediaStreamOpen: false,
          isAudioActive: false,
          isVideoActive: false
        }
      }
    })
  },
  { immediate: true, deep: true }
)

// 监听房间状态变化
watch(inRoom, newVal => {
  if (newVal) {
    // initializeMedia()
  } else {
    cleanupMedia()
  }
})

// 初始化
onMounted(() => {
  initializeMedia()
})

const toggleCameraSource = () => {
  localMedia.value.flipCamera()
}

// 初始化媒体连接
const initializeMedia = () => {
  if (!roomId.value || !inRoom.value) return

  localMedia.value?.initialize()
  isConnected.value = true
  hasError.value = false
  updateConnectionStatus()

  // 发送加入通知
  emit('sendMediaData', {
    type: 'startCall',
    data: { targetId: roomId.value }
  })
}

// 清理媒体资源
const cleanupMedia = () => {
  localMedia.value?.cleanup()
  // 清理所有远程用户媒体
  Object.values(remoteMedias.value).forEach(media => media?.cleanup())

  // 重置状态
  localStatus.value = { isMicrophoneOn: false, isCameraOn: false }
  remoteStatus.value = {}
  streamTimers.value = {}
  isConnected.value = false
  connectionStatus.value = '未连接'

  // 发送离开通知
  emit('sendMediaData', {
    type: 'endCall',
    data: { targetId: roomId.value }
  })
}

// 数据打包函数（新增senderId）
function packData(type, targetId, senderId, dataBuffer) {
  const targetIdBytes = new TextEncoder().encode(targetId)
  const senderIdBytes = new TextEncoder().encode(senderId)
  const targetIdLength = targetIdBytes.length
  const senderIdLength = senderIdBytes.length

  // 数据结构：[类型(1)][目标ID长度(1)][发送者ID长度(1)][目标ID][发送者ID][数据]
  const totalLength = 1 + 1 + 1 + targetIdLength + senderIdLength + dataBuffer.byteLength
  const buffer = new ArrayBuffer(totalLength)
  const view = new DataView(buffer)

  view.setUint8(0, type)
  view.setUint8(1, targetIdLength)
  view.setUint8(2, senderIdLength)

  let offset = 3
  new Uint8Array(buffer).set(targetIdBytes, offset)
  offset += targetIdLength

  new Uint8Array(buffer).set(senderIdBytes, offset)
  offset += senderIdLength

  new Uint8Array(buffer).set(new Uint8Array(dataBuffer), offset)

  return buffer
}

// 解包函数（新增senderId解析）
function unpackData(buffer) {
  const view = new DataView(buffer)

  // 读取类型
  const type = view.getUint8(0)

  // 读取目标ID和发送者ID长度
  const targetIdLength = view.getUint8(1)
  const senderIdLength = view.getUint8(2)

  // 读取目标ID
  let offset = 3
  const targetIdBytes = new Uint8Array(buffer, offset, targetIdLength)
  offset += targetIdLength

  // 读取发送者ID
  const senderIdBytes = new Uint8Array(buffer, offset, senderIdLength)
  offset += senderIdLength

  // 读取数据
  const dataLength = buffer.byteLength - offset
  const data = buffer.slice(offset)

  return {
    type,
    targetId: new TextDecoder().decode(targetIdBytes),
    senderId: new TextDecoder().decode(senderIdBytes),
    data
  }
}

// 处理本地流数据（添加senderId）
const handleLocalStream = data => {
  if (!inRoom.value || !isConnected.value || !roomId.value) return
  let type = 1 // audio
  if (data.type === 'video') {
    type = 3 //非首帧
    if (data.first) {
      type = 4 // 首帧
    }
  }
  // 打包数据：类型、房间ID、当前用户ID、媒体数据
  emit('sendMediaBuffer', packData(type, roomId.value, currentUserId.value, data.buffer))
}

// 处理本地状态变化（保持不变）
const handleLocalStatusChange = status => {
  localStatus.value = { ...localStatus.value, ...status }
  updateConnectionStatus()
}

// 处理远程数据（分发到对应用户的媒体组件）
const handleMediaData = async blob => {
  try {
    console.log('handleMediaData')
    const blobBuffer = await blob.arrayBuffer()
    const { type, senderId, data } = unpackData(blobBuffer)
    let realType = 'audio' // 1
    if (type >= 3) {
      realType = 'video' // 非首帧
      if (type === 4) {
        realType = 'videoFirst' //首帧
      }
    }

    // 转发数据到对应用户的媒体组件
    if (remoteMedias.value[senderId]) {
      // // 更新状态并重置计时器
      updateRemoteStatus(senderId, realType)
      resetStreamTimer(senderId, realType)
      remoteMedias.value[senderId].receiveBuffer(realType, data, remoteStatus.value[senderId].isMediaStreamOpen)
    }
  } catch (error) {
    console.error('处理远程媒体数据失败:', error)
  }
}

// 更新远程用户状态
const updateRemoteStatus = async (userId, type) => {
  if (!remoteStatus.value[userId]) {
    remoteStatus.value[userId] = { isAudioActive: false, isVideoActive: false, isMediaStreamOpen: false }
  }

  // 视频流恢复时调用初始化方法
  if (type === MEDIA_TYPES.VIDEOFIRST) {
    console
    remoteStatus.value[userId].isVideoActive = true
    if (!remoteStatus.value[userId].isMediaStreamOpen) {
      remoteStatus.value[userId].isMediaStreamOpen = true
      remoteMedias.value[userId]?.initMediaSource()
    }
  } else {
    remoteStatus.value[userId].isAudioActive = true
  }
}

// 重置数据流计时器（1秒无数据则标记为关闭）
const resetStreamTimer = (userId, type) => {
  if (type === 'videoFirst') {
    return
  }
  // 清除旧计时器
  if (streamTimers.value[userId]?.[type]) {
    clearTimeout(streamTimers.value[userId][type])
  } else {
    streamTimers.value[userId] = { ...streamTimers.value[userId] }
  }

  // 设置新计时器（1秒后标记为关闭）
  streamTimers.value[userId][type] = setTimeout(() => {
    if (type === MEDIA_TYPES.AUDIO) {
      remoteStatus.value[userId].isAudioActive = false
    } else {
      remoteStatus.value[userId].isVideoActive = false
      remoteMedias.value[userId]?.stopVideoStream()
      remoteStatus.value[userId].isMediaStreamOpen = false
    }
  }, 1000)
}

// 切换麦克风（保持不变）
const toggleMicrophone = async () => {
  if (!localMedia.value || !inRoom.value) return
  localMedia.value.toggleMicrophone()
}

// 切换摄像头（保持不变）
const toggleCamera = async () => {
  if (!localMedia.value || !inRoom.value || !isVideoSupported.value) return
  localMedia.value.toggleCamera()
}

// 结束通话（保持不变）
const endMediaCall = () => {
  if (!inRoom.value) return

  localMedia.value?.stop()
  localStatus.value = { isMicrophoneOn: false, isCameraOn: false }
  Object.values(remoteMedias.value).forEach(media => media?.stop())
  remoteStatus.value = {}
  updateConnectionStatus()

  emit('sendMediaData', {
    type: 'endCall',
    data: { targetId: roomId.value }
  })
}

// 更新连接状态文本
const updateConnectionStatus = () => {
  if (!inRoom.value) {
    connectionStatus.value = '未进入房间'
    return
  }

  const baseStatus =
    localStatus.value.isMicrophoneOn && localStatus.value.isCameraOn
      ? '正在进行音视频通话'
      : localStatus.value.isMicrophoneOn
      ? '正在进行语音通话'
      : localStatus.value.isCameraOn
      ? '正在进行视频通话（静音）'
      : '已连接，点击按钮开启音视频'

  connectionStatus.value = `${baseStatus} `
}

// 错误处理
const handleMediaError = err => {
  hasError.value = true
  connectionStatus.value = `错误: ${err.message}`
  console.error('媒体组件错误:', err)
}

// 暴露方法给父组件
defineExpose({
  handleMediaData,
  endMediaCall
})

// 定义事件
const emit = defineEmits(['sendMediaBuffer', 'sendMediaData'])
</script>

<style scoped>
/* 仅修改视频容器样式以支持多用户 */
.video-container {
  flex: 1;
  display: flex;
  flex-wrap: wrap; /* 支持换行 */
  gap: 1rem;
  margin-bottom: 1rem;
  min-height: 300px;
  overflow: auto; /* 超出时滚动 */
}

/* 本地视频和远程视频自适应 */
.local-video-wrapper,
.remote-video-wrapper {
  position: relative;
  flex: 1;
  min-width: calc(50% - 1rem); /* 最小宽度 */
  min-height: calc(50% - 1rem);
  /* height: 200px; */
  background-color: #000;
  border-radius: 0.5rem;
  overflow: hidden;
}
/* .local-video-wrapper,
.remote-video-wrapper {
  position: relative;
  flex: 1;
  min-width: calc(33.333% - 1rem); 
  min-height: calc(33.333% - 1rem);
  background-color: #000;
  border-radius: 0.5rem;
  overflow: hidden;
} */

/* 其他样式保持不变 */
.media-chat {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
  padding: 1rem;
  background-color: #f8f9fa;
  border-radius: 0.5rem;
  box-sizing: border-box;
}

.video-element {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.video-element.disabled {
  filter: grayscale(1) opacity(0.5);
}

.overlay-message {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #fff;
  background-color: rgba(0, 0, 0, 0.5);
  padding: 0.5rem 1rem;
  border-radius: 0.25rem;
}

.no-signal {
  background-color: #222;
  position: relative;
}

.no-signal::after {
  content: '等待房间内其他用户...';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #888;
}

.video-label {
  position: absolute;
  bottom: 0;
  left: 0;
  padding: 0.25rem 0.5rem;
  background-color: rgba(0, 0, 0, 0.5);
  color: white;
  font-size: 0.875rem;
}

.video-status {
  position: absolute;
  top: 0;
  right: 0;
  padding: 0.25rem 0.5rem;
  background-color: rgba(0, 0, 0, 0.5);
  color: white;
  font-size: 0.875rem;
}

.controls {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

button {
  flex: 1;
  padding: 0.75rem 1rem;
  border: none;
  border-radius: 0.375rem;
  background-color: #0d6efd;
  color: white;
  font-size: 1rem;
  cursor: pointer;
  transition: background-color 0.2s;
}

button:disabled {
  background-color: #6c757d;
  cursor: not-allowed;
  opacity: 0.7;
}

.hangup-button {
  background-color: #dc3545;
}

.status-bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem;
  background-color: #e9ecef;
  border-radius: 0.375rem;
}

.status-indicator {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background-color: #888;
}

.status-indicator.active {
  background-color: #28a745;
  animation: pulse 2s infinite;
}

.connection-status {
  flex: 1;
  font-size: 0.875rem;
  color: #333;
}

.connection-status.connected {
  color: #28a745;
}

.connection-status.error {
  color: #dc3545;
}

.connection-status.disabled {
  color: #6c757d;
}

.unsupported-indicator {
  margin-left: 0.5rem;
  font-size: 0.75rem;
  background-color: #ffc107;
  color: #000;
  padding: 0.125rem 0.25rem;
  border-radius: 0.25rem;
}

@keyframes pulse {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
  100% {
    opacity: 1;
  }
}
</style>


